/*
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Library General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 */

#ifdef HAVE_CONFIG_H
# include "config.h"
#endif

#include "DialogBookEditor.h"
#include <string.h>
//#define _DEBUG_


DialogBookEditor::DialogBookEditor(Book* pbook)
: book(pbook),
  calendar(*this),
  table(7, 2),
  label_author(_("Author:"), 0, 0.5),
  label_title(_("Title:"), 0, 0.5),
  label_isbn(_("ISBN:"), 0, 0.5),
  label_category(_("Category:"), 0, 0.5),
  label_rating(_("Rating:"), 0, 0.5),
  label_readdate(_("Read:"), 0, 0.5),
  image_readdate(PACKAGE_PIXMAPS_DIR "/calendar.png"),
  label_summary(_("Summary:"), 0, 0.5),
  label_review(_("Review:"), 0, 0.5),
  button_cancel(Gtk::Stock::CANCEL),
  button_save(Gtk::Stock::SAVE)
{
  set_size_request(450, -1);
  table.set_row_spacings(3);
  table.set_col_spacings(12);
  table.set_border_width(12);
  add(table);
  
  // Author.
  table.attach(label_author, 0, 1, 0, 1, Gtk::FILL, Gtk::FILL);
  table.attach(entry_author, 1, 2, 0, 1, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  entry_author.set_text(book->get_author());
  
  // Title.
  table.attach(label_title, 0, 1, 1, 2, Gtk::FILL, Gtk::FILL);
  table.attach(entry_title, 1, 2, 1, 2, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  entry_title.signal_changed().connect(
    sigc::mem_fun(*this, &DialogBookEditor::on_entry_title_changed));
  entry_title.set_text(book->get_title());
  
  // ISBN-Number.
  table.attach(label_isbn, 0, 1, 2, 3, Gtk::FILL, Gtk::FILL);
  table.attach(entry_isbn, 1, 2, 2, 3, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  entry_isbn.set_text(book->get_isbn());
  
  // Category.
  table.attach(label_category, 0, 1, 3, 4, Gtk::FILL, Gtk::FILL);
  combo_category.append_text(_("Biography"));
  combo_category.append_text(_("Children"));
  combo_category.append_text(_("Classic"));
  combo_category.append_text(_("Drama"));
  combo_category.append_text(_("Fiction"));
  combo_category.append_text(_("Health"));
  combo_category.append_text(_("History"));
  combo_category.append_text(_("Horror"));
  combo_category.append_text(_("Humor"));
  combo_category.append_text(_("Other"));
  combo_category.append_text(_("Poetry"));
  combo_category.append_text(_("Reference"));
  combo_category.append_text(_("Religion"));
  combo_category.append_text(_("Romance"));
  combo_category.append_text(_("Science"));
  combo_category.append_text(_("Science Fiction"));
  combo_category.append_text(_("Thriller"));
  table.attach(combo_category, 1, 2, 3, 4, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  Gtk::Entry *entry_category = (Gtk::Entry*)combo_category.get_child();
  entry_category->set_text(book->get_category());
  
  // Rating.
  table.attach(label_rating, 0, 1, 4, 5, Gtk::FILL, Gtk::FILL);
  combo_rating.append_text(_("Not yet rated"));
  int i;
  for (i = 0; i <= 10; i++) {
    char number[3];
    snprintf(number, 3, "%i", i);
    combo_rating.append_text(number);
  }
  combo_rating.set_active(book->get_rating() + 1);
  table.attach(combo_rating, 1, 2, 4, 5, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  
  // Read date selector.
  table.attach(label_readdate, 0, 1, 5, 6, Gtk::FILL, Gtk::FILL);
  button_readdate.add(image_readdate);
  hbox_readdate.set_spacing(3);
  hbox_readdate.pack_start(entry_readdate, TRUE, TRUE);
  hbox_readdate.pack_start(button_readdate, FALSE, FALSE);
  table.attach(hbox_readdate,  1, 2, 5, 6, Gtk::EXPAND|Gtk::FILL, Gtk::FILL);
  entry_readdate.set_text(book->get_readdate_string());
  button_readdate.signal_clicked().connect(
    sigc::mem_fun(*this, &DialogBookEditor::on_button_readdate_clicked));
  table.set_row_spacing(5, 12);
  
  // Summary
  table.attach(label_summary, 0, 2, 6, 7, Gtk::FILL, Gtk::FILL);
  scroll_summary.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  scroll_summary.set_shadow_type(Gtk::SHADOW_IN);
  text_summary.set_wrap_mode(Gtk::WRAP_WORD);
  scroll_summary.add(text_summary);
  table.attach(scroll_summary, 0, 2, 7, 8);
  table.set_row_spacing(7, 12);
  text_summary.get_buffer()->set_text(book->get_summary());
  
  // Review
  table.attach(label_review, 0, 2, 8, 9, Gtk::FILL, Gtk::FILL);
  scroll_review.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
  scroll_review.set_shadow_type(Gtk::SHADOW_IN);
  text_review.set_wrap_mode(Gtk::WRAP_WORD);
  scroll_review.add(text_review);
  table.attach(scroll_review, 0, 2, 9, 10);
  table.set_row_spacing(9, 12);
  text_review.get_buffer()->set_text(book->get_review());
  
  // Buttons
  {
    buttonbox.set_spacing(12);
    table.attach(buttonbox, 0, 2, 10, 11, Gtk::FILL, Gtk::FILL);
    
    // Add some distance.
    buttonbox.pack_start(fixed, TRUE, TRUE);
    
    // "Cancel".
    button_cancel.set_size_request(-1, 35);
    buttonbox.pack_start(button_cancel, FALSE, TRUE);
    button_cancel.signal_clicked().connect(
      sigc::mem_fun(*this, &DialogBookEditor::on_button_cancel_clicked));
    
    // "Save".
    button_save.set_size_request(-1, 35);
    buttonbox.pack_start(button_save, FALSE, TRUE);
    button_save.signal_clicked().connect(
      sigc::mem_fun(*this, &DialogBookEditor::on_button_save_clicked));
  }
  
  signal_expose_event().connect(
      sigc::mem_fun(*this, &DialogBookEditor::on_window_expose_event));
  signal_delete_event().connect(
      sigc::mem_fun(*this, &DialogBookEditor::on_window_delete_event));
  
  show_all();
}


DialogBookEditor::~DialogBookEditor()
{
}


Book* DialogBookEditor::get_book(void)
{
  return book;
}


void DialogBookEditor::on_entry_title_changed(void)
{
  string title = entry_title.get_text();
  set_title(title != "" ? title : _("Unnamed Book"));
}


void DialogBookEditor::on_button_readdate_clicked(void)
{
  if (calendar.is_visible()) {
    calendar.hide();
    calendar_signal_selected.disconnect();
    return;
  }
  
  struct tm date;
  date = book->get_readdate();
  struct tm undefined;
  memset(&undefined, 0, sizeof(tm));
  if (memcmp(&date, &undefined, sizeof(tm)) != 0) {
    calendar.calendar.select_month(date.tm_mon, date.tm_year + 1900);
    calendar.calendar.select_day(date.tm_mday);
  }
  calendar_signal_selected =
    calendar.calendar.signal_day_selected().connect(
        sigc::mem_fun(*this, &DialogBookEditor::on_calendar_readdate_selected));
  calendar.calendar.signal_day_selected_double_click().connect(
   sigc::mem_fun(*this, &DialogBookEditor::on_calendar_readdate_doubleclicked));
  calendar.show();
  
  on_window_expose_event(NULL);
}


void DialogBookEditor::on_calendar_readdate_selected(void)
{
#ifdef _DEBUG_
  printf("DialogBookEditor::on_calendar_readdate_selected(): Called.\n");
#endif
  unsigned int year, month, day;
  calendar.calendar.get_date(year, month, day);
  book->set_readdate(year, month, day);
  entry_readdate.set_text(book->get_readdate_string());
}


void DialogBookEditor::on_calendar_readdate_doubleclicked(void)
{
#ifdef _DEBUG_
  printf("DialogBookEditor::on_calendar_readdate_doubleclicked(): Called.\n");
#endif
  calendar.hide();
  calendar_signal_selected.disconnect();
}


void DialogBookEditor::on_button_cancel_clicked(void)
{
#ifdef _DEBUG_
  printf("DialogBookEditor::on_button_cancel_clicked(): Called.\n");
#endif
  signal_button_cancel_clicked.emit(this, book);
}


void DialogBookEditor::on_button_save_clicked(void)
{
#ifdef _DEBUG_
  printf("DialogBookEditor::on_button_save_clicked(): Called.\n");
#endif
  book->set_author(entry_author.get_text());
  book->set_title(entry_title.get_text());
  book->set_isbn(entry_isbn.get_text());
  Gtk::Entry *entry_category = (Gtk::Entry*)combo_category.get_child();
  book->set_category(entry_category->get_text());
  book->set_summary(text_summary.get_buffer()->get_text());
  book->set_review(text_review.get_buffer()->get_text());
  book->set_rating(combo_rating.get_active_row_number() - 1);
  book->set_readdate_string(entry_readdate.get_text());
  
  signal_button_save_clicked.emit(this, book);
}


bool DialogBookEditor::on_window_delete_event(GdkEventAny* trash)
{
  on_button_cancel_clicked();
  return FALSE;
}


bool DialogBookEditor::on_window_expose_event(GdkEventExpose* trash)
{
  int win_x, win_y;
  int button_x, button_y, button_w, button_h;
  int cal_w;
  button_readdate.get_window()->get_position(win_x, win_y);
  button_x = button_readdate.get_allocation().get_x();
  button_y = button_readdate.get_allocation().get_y();
  button_w = button_readdate.get_width();
  button_h = button_readdate.get_height();
  cal_w    = calendar.calendar.get_width();
  calendar.move(win_x + button_x, win_y + button_y + button_h);
  return TRUE;
}
